package com.hotel.user.interceptor;

import com.hotel.common.entity.Permission;
import com.hotel.common.utils.BusinessException;
import com.hotel.common.utils.Result;
import com.hotel.user.service.PermissionService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.List;

@Component
public class PermissionInterceptor implements HandlerInterceptor {

    @Autowired
    private PermissionService permissionService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取当前用户ID（这里假设从请求头中获取，实际应该从token中解析）
        String userIdStr = request.getHeader("X-User-Id");
        if (userIdStr == null) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(Result.error("未登录").toString());
            return false;
        }

        Long userId = Long.parseLong(userIdStr);
        String requestUri = request.getRequestURI();
        String method = request.getMethod();

        // 超级管理员（ID=1）拥有全部权限，直接放行
        if (userId == 1L) {
            return true;
        }

        // 获取用户权限列表
        List<Permission> userPermissions = permissionService.getPermissionsByUserId(userId).getData();
        // 若具备管理员总权限，则放行
        if (userPermissions != null) {
            for (Permission p : userPermissions) {
                if ("admin:all".equalsIgnoreCase(p.getPermissionCode())) {
                    return true;
                }
            }
        }
        
        // 检查是否有权限访问该接口
        boolean hasPermission = checkPermission(requestUri, method, userPermissions);
        
        if (!hasPermission) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(Result.error("没有权限访问该资源").toString());
            return false;
        }

        return true;
    }

    private boolean checkPermission(String requestUri, String method, List<Permission> userPermissions) {
        String required = null;

        // 资源判断
        boolean isUserApi = requestUri.startsWith("/api/users");
        boolean isRoleApi = requestUri.startsWith("/api/roles");
        boolean isPermissionApi = requestUri.startsWith("/api/permissions");
        boolean isHotelApi = requestUri.startsWith("/api/hotels");
        boolean isRoomApi = requestUri.startsWith("/api/rooms");
        boolean isOrderApi = requestUri.startsWith("/api/orders");
        boolean isPaymentApi = requestUri.startsWith("/api/payments");

        // 特例放行：用于前端同步当前用户的角色/权限
        if ("GET".equalsIgnoreCase(method)
                && (requestUri.matches("^/api/roles/user/\\d+$")
                || requestUri.matches("^/api/permissions/user/\\d+$"))) {
            return true;
        }

        // 动作判断：根据HTTP方法和路径语义推断
        if (isUserApi) {
            if ("GET".equalsIgnoreCase(method)) {
                required = "user:search";
            } else if ("POST".equalsIgnoreCase(method)) {
                required = "user:create";
            } else if ("PUT".equalsIgnoreCase(method)) {
                required = "user:update";
            } else if ("DELETE".equalsIgnoreCase(method)) {
                required = "user:delete";
            }
        } else if (isRoleApi) {
            // 分配/移除权限走 role:assign，其余角色管理走 role:manage
            boolean isAssignPermission = requestUri.matches(".*/permissions/.*") || requestUri.endsWith("/permissions");
            if (isAssignPermission) {
                required = "role:assign";
            } else {
                required = "role:manage";
            }
        } else if (isPermissionApi) {
            // 当前SQL无 permission:*，使用 role:manage 作为权限查询与管理的控制
            required = "role:manage";
        } else if (isHotelApi) {
            if ("GET".equalsIgnoreCase(method)) {
                required = "hotel:search";
            } else if ("POST".equalsIgnoreCase(method)) {
                required = "hotel:create";
            } else if ("PUT".equalsIgnoreCase(method)) {
                required = "hotel:update";
            } else if ("DELETE".equalsIgnoreCase(method)) {
                required = "hotel:delete";
            }
        } else if (isRoomApi) {
            if ("GET".equalsIgnoreCase(method)) {
                required = "room:search";
            } else if ("POST".equalsIgnoreCase(method)) {
                required = "room:create";
            } else if ("PUT".equalsIgnoreCase(method)) {
                required = "room:update";
            } else if ("DELETE".equalsIgnoreCase(method)) {
                required = "room:delete";
            }
        } else if (isOrderApi) {
            if ("GET".equalsIgnoreCase(method)) {
                required = "order:search";
            } else if ("POST".equalsIgnoreCase(method)) {
                required = "order:create";
            } else if ("DELETE".equalsIgnoreCase(method)) {
                required = "order:cancel";
            }
        } else if (isPaymentApi) {
            if ("GET".equalsIgnoreCase(method)) {
                required = "payment:search";
            } else if ("POST".equalsIgnoreCase(method)) {
                required = "payment:pay";
            } else if ("DELETE".equalsIgnoreCase(method)) {
                required = "payment:refund";
            }
        }

        if (required == null) {
            return false;
        }

        for (Permission permission : userPermissions) {
            if (required.equalsIgnoreCase(permission.getPermissionCode())) {
                return true;
            }
        }
        return false;
    }
}